﻿using System;
using System.Linq;

namespace Reloaded.MWOSiteReader
{
	public static class MWOGameData
	{
		public static System.Collections.Generic.List<WeaponSystemInfo> GetInternalWeaponStatistics()
		{
			var result = new System.Collections.Generic.List<WeaponSystemInfo>();

			var httpClient = new System.Net.Http.HttpClient(
				new System.Net.Http.HttpClientHandler
				{
					AllowAutoRedirect = true,
					UseCookies = true
				});

			var baseDataUri = new Uri(new Uri(MWOConfiguration.APIUrlBase, UriKind.Absolute), "/api/items/list/full.json");

			var theRequest = httpClient.GetStreamAsync(baseDataUri).ContinueWith(s =>
			{
				using (var reader = new System.IO.StreamReader(s.Result))
				{
					var topObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadToEnd());

					result = topObject.Properties()
						.Select(o => o.First() as Newtonsoft.Json.Linq.JObject)
						.Where(o => o["stats"] != null && o.Value<string>("category").Equals("weapon"))
						.Select(o => new
						{
							Name = o.Value<string>("name"),
							BaseDamage = o["stats"].Value<double>("damage"),
							NumPerShot = (o["stats"]["numPerShot"] != null) ? o["stats"].Value<int>("numPerShot") : 1,
							NumFiring = (o["stats"]["numFiring"] != null) ? o["stats"].Value<int>("numFiring") : 1,
							Crit1 = 0.25 + ((o["stats"]["critChanceIncrease"] != null) ? double.Parse(o["stats"].Value<string>("critChanceIncrease").Split(',').First()) : 0.0),
							Crit2 = 0.14 + ((o["stats"]["critChanceIncrease"] != null) ? double.Parse(o["stats"].Value<string>("critChanceIncrease").Split(',').Skip(1).First()) : 0.0),
							Crit3 = 0.03 + ((o["stats"]["critChanceIncrease"] != null) ? double.Parse(o["stats"].Value<string>("critChanceIncrease").Split(',').Last()) : 0.0),
							CritDamage = o["stats"].Value<double>("damage") * ((o["stats"]["critDamMult"] != null) ? o["stats"].Value<double>("critDamMult") : 1.0),
							IsBullet = o["stats"].Value<string>("projectileclass").Equals("bullet"),
						})
						.Select(o => new
						{
							Name = o.Name,
							BaseDamage = o.BaseDamage,
							BestDamage = ((100.0 * o.BaseDamage) + (((o.Crit1 * 100.0) * (o.CritDamage * 1.0)) + ((o.Crit2 * 100.0) * (o.CritDamage * 2.0)) + ((o.Crit3 * 100.0) * (o.CritDamage * 3.0))) * 0.10) / 100.0,
							NumPerShot = o.NumPerShot,
							NumFiring = o.NumFiring,
							IsBullet = o.IsBullet,
							NumTracked = (o.IsBullet) ? (o.NumFiring * o.NumPerShot) : o.NumPerShot,
						})
						.Select(o => new WeaponSystemInfo
						{
							Name = o.Name,
							Damage = o.BaseDamage * (double)o.NumTracked,
							BestDamage = o.BestDamage * (double)o.NumTracked,
						})
						.ToList();
				}
			});

			theRequest.Wait();

			if (theRequest.Exception != null)
				throw new Exception("Failed to parse source content: Internal Weapon Statistics", theRequest.Exception);

			return (result);
		}
	}
}